Converted these images to PNG, saving a handful of bytes per image
[adiumx.git] / Plugins / Message Alias Support / AIMessageAliasPlugin.m
blob63e57a8f546b8a2f251b3e6730ac1f7700dac8b4
1 /* 
2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
3  * with this source distribution.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6  * General Public License as published by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
11  * Public License for more details.
12  * 
13  * You should have received a copy of the GNU General Public License along with this program; if not,
14  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15  */
17 #import "AIMessageAliasPlugin.h"
18 #import <Adium/AIContentControllerProtocol.h>
19 #import <Adium/AIAccountControllerProtocol.h>
20 #import <AIUtilities/AIAttributedStringAdditions.h>
21 #import <AIUtilities/AIDateFormatterAdditions.h>
22 #import <Adium/AIAccount.h>
23 #import <Adium/AIContentMessage.h>
24 #import <Adium/AIContentObject.h>
25 #import <Adium/AIListContact.h>
27 @interface AIMessageAliasPlugin (PRIVATE)
28 - (NSMutableAttributedString *)replaceKeywordsInString:(NSAttributedString *)original context:(id)context;
29 @end
31 @implementation AIMessageAliasPlugin
33 - (void)installPlugin
35     //Register us as a filter
36         [[adium contentController] registerContentFilter:self ofType:AIFilterDisplay direction:AIFilterIncoming];
37         [[adium contentController] registerContentFilter:self ofType:AIFilterAutoReplyContent direction:AIFilterOutgoing];
38         [[adium contentController] registerContentFilter:self ofType:AIFilterTooltips direction:AIFilterIncoming];
39         [[adium contentController] registerContentFilter:self ofType:AIFilterContactList direction:AIFilterIncoming];
42 - (void)uninstallPlugin
44         [[adium contentController] unregisterContentFilter:self];
47 - (NSAttributedString *)filterAttributedString:(NSAttributedString *)inAttributedString context:(id)context
49         if (!inAttributedString || ![inAttributedString length]) return inAttributedString;
51         //Filter keywords in the message
52         NSMutableAttributedString       *filteredMessage = [self replaceKeywordsInString:inAttributedString context:context];;
54         //Filter keywords in URLs (For AIM subprofile links, mostly)
55         int     length = [(filteredMessage ? filteredMessage : inAttributedString) length];
56         NSRange scanRange = NSMakeRange(0, 0);
57         while (NSMaxRange(scanRange) < length) {
58                 id linkURL = [(filteredMessage ? filteredMessage : inAttributedString) attribute:NSLinkAttributeName
59                                                                                                                                                                  atIndex:NSMaxRange(scanRange)
60                                                                                                                                                   effectiveRange:&scanRange];
61                 if (linkURL) {
62                         NSString        *linkURLString;
63                         
64                         if ([linkURL isKindOfClass:[NSURL class]]) {
65                                 linkURLString = (NSString *)CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault,
66                                                                                                                                                                            (CFStringRef)[(NSURL *)linkURL absoluteString],
67                                                                                                                                                                            /* characters to leave escaped */ CFSTR(""));
68                                 [linkURLString autorelease];
69                                 
70                         } else {
71                                 linkURLString = (NSString *)linkURL;
72                         }
73                         
74                         if (linkURLString) {
75                                 //If we found a URL, replace any keywords within it
76                                 NSString        *result = [[self replaceKeywordsInString:[NSAttributedString stringWithString:linkURLString]
77                                                                                                                          context:context] string];
78                                 
79                                 if (result) {
80                                         NSURL           *newURL;
81                                         NSString        *escapedLinkURLString;
82                                         NSString        *charactersToLeaveUnescaped = @"#";
83                                         
84                                         if (!filteredMessage) filteredMessage = [[inAttributedString mutableCopy] autorelease];
85                                         escapedLinkURLString = (NSString *)CFURLCreateStringByAddingPercentEscapes(/* allocator */ kCFAllocatorDefault,
86                                                                                                                                                                                            (CFStringRef)result,
87                                                                                                                                                                                            (CFStringRef)charactersToLeaveUnescaped,
88                                                                                                                                                                                            /* legal characters to escape */ NULL,
89                                                                                                                                                                                            kCFStringEncodingUTF8);
90                                         newURL = [NSURL URLWithString:escapedLinkURLString];
91                                         
92                                         if (newURL) {
93                                                 [filteredMessage addAttribute:NSLinkAttributeName
94                                                                                                 value:newURL
95                                                                                                 range:scanRange];
96                                         }
97                                         [escapedLinkURLString release];
98                                 }
99                         }
100                 }
101         }
102         
103     return (filteredMessage ? filteredMessage : inAttributedString);
106 - (float)filterPriority
108         return DEFAULT_FILTER_PRIORITY;
111 //Replace any keywords in the passed string
112 //Returns a mutable version of the passed string if keywords have been replaced.  Otherwise returns
113 - (NSMutableAttributedString *)replaceKeywordsInString:(NSAttributedString *)attributedString context:(id)context
115         NSString                                        *str = [attributedString string];
116         NSMutableAttributedString       *newAttributedString = nil;
118         //Our Name
119         //If we're passed content, our account will be the destination of that content
120         //If we're passed a list object, we can use the name of the preferred account for that object
121         if ([str rangeOfString:@"%n"].location != NSNotFound) {
122                 NSString        *replacement = nil;
124                 if ([context isKindOfClass:[AIContentObject class]]) {
125                         replacement = [[context destination] UID]; //This exists primarily for AIM compatibility; AIM uses the UID (no formatting).
126                 } else if ([context isKindOfClass:[AIListContact class]]) {
127                         replacement = [[[adium accountController] preferredAccountForSendingContentType:CONTENT_MESSAGE_TYPE
128                                                                                                                                                                   toContact:context] formattedUID];
129                 }
131                 if (replacement) {
132                         if (!newAttributedString) newAttributedString = [[attributedString mutableCopy] autorelease];
133                         
134                         [newAttributedString replaceOccurrencesOfString:@"%n"
135                                                                                                  withString:replacement
136                                                                                                         options:NSLiteralSearch
137                                                                                                           range:NSMakeRange(0, [newAttributedString length])];
138                 }
139         }
141         //Current Date
142         if ([str rangeOfString:@"%d"].location != NSNotFound) {
143                 NSCalendarDate  *currentDate = [NSCalendarDate calendarDate];
144                 NSString                *calendarFormat = [[NSUserDefaults standardUserDefaults] objectForKey:NSShortDateFormatString];
146                 if (!newAttributedString) newAttributedString = [[attributedString mutableCopy] autorelease];
147                 
148                 [newAttributedString replaceOccurrencesOfString:@"%d"
149                                                                                          withString:[currentDate descriptionWithCalendarFormat:calendarFormat]
150                                                                                                 options:NSLiteralSearch
151                                                                                                   range:NSMakeRange(0, [newAttributedString length])];
152         }
153         
154         //Current Time
155         if ([str rangeOfString:@"%t"].location != NSNotFound) {
156                 NSCalendarDate  *currentDate = [NSCalendarDate calendarDate];
157                 NSString                *localDateFormat = [NSDateFormatter localizedDateFormatStringShowingSeconds:YES
158                                                                                                                                                                           showingAMorPM:YES];
159                 
160                 if (!newAttributedString) newAttributedString = [[attributedString mutableCopy] autorelease];
162                 [newAttributedString replaceOccurrencesOfString:@"%t"
163                                                                                          withString:[currentDate descriptionWithCalendarFormat:localDateFormat]
164                                                                                                 options:NSLiteralSearch
165                                                                                                   range:NSMakeRange(0, [newAttributedString length])];
166         }
167         
168         return newAttributedString;
171 @end